﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using Invoicing.Model.Orders;
using Invoicing.Model.Members;
using Invoicing.Model.Products;
using Invoicing.Model.Financial;
using Utils;
namespace Invoicing.Command.Orders
{
    public class ProductOrderCommand
    {
        public static ProductOrderModel NewOrder(ProductOrderModel order) 
        {
            if (order != null)
            {
                using (DBCentre db = new DBCentre())
                {
                    var orderMethod = (OrderMethod)Enum.Parse(typeof(OrderMethod), order.Method.ToString());
                    order.OrderNo = Comm.Orders.CreateOrderNo(db, orderMethod);
                    var dOrder = Convertor.ConvertFrom<ProductOrder, ProductOrderModel>(order);

                    foreach (var it in order.Items)
                    {
                        var quantity = it.Quantity;
                        if (orderMethod == OrderMethod.CK || orderMethod == OrderMethod.CT)
                            quantity *= -1;
                        decimal lastStock = 0; //上期库存
                        var stock = db.DataContext.ProductStocks.FirstOrDefault(p => p.HouseID==order.HouseID &&p.ProductID == it.ProductID && p.MaterialID == it.MaterialID && p.ProcessID == it.ProcessID && p.Size==it.Size);
                        if (stock != null)
                        {
                            lastStock = stock.Quantity;
                            stock.Quantity = it.Balance = lastStock + quantity;
                            stock.LastUpdateOn = DateTime.Now;
                        }
                        else
                        {
                            it.Balance = it.Quantity;
                            stock = new ProductStock()
                            {
                                ProductID = it.ProductID,
                                MaterialID = it.MaterialID,
                                ProcessID = it.ProcessID,
                                Size=it.Size,
                                Quantity = quantity,
                                LastUpdateOn = DateTime.Now,
                                HouseID=order.HouseID
                            };
                            db.DataContext.ProductStocks.Add(stock);
                        }
                        if (lastStock + quantity < 0)
                        {
                            var material = db.DataContext.ProductMaterials.FirstOrDefault(p => p.ID == it.MaterialID);
                            var process = db.DataContext.ProductProcesses.FirstOrDefault(p => p.ID == it.ProcessID);
                            throw new InvoicingException(string.Format("{0} {1} {2} {3} 库存不足，目前库存量为：{4}", new object[] { it.Product.Module, material.MaterialName, process.ProcessName, it.Size, lastStock }));
                        }
                         
                        var dit = Convertor.ConvertFrom<ProductOrderDetail, ProductOrderDetailModel>(it);
                        dOrder.ProductOrderDetails.Add(dit);
                    }
                    db.DataContext.ProductOrders.Add(dOrder);

                    #region 修改交易单据的状态 判断是否已经完成库存操作
                    if (order.AssociatedDealID > 0)
                    {
                        var dealOrder = db.DataContext.DealOrders.FirstOrDefault(p => p.ID == order.AssociatedDealID && new int[] { 1, 3 }.Contains(p.OrderStatus));
                        if (dealOrder != null)
                        {
                            
                            var deal_items = dealOrder.DealOrderDetails.ToList();
                            var pro_orders = dealOrder.ProductOrders.ToList();
                            var hasDone = true;
                            deal_items.ForEach(p =>
                            {
                                decimal qua = 0;
                                pro_orders.ForEach(o =>
                                {
                                    qua += o.ProductOrderDetails.Where(r => r.ProductID == p.ProductID && r.MaterialID==p.MaterialID && r.ProcessID==p.ProcessID && r.Size==p.Size).Sum(r => r.Quantity);
                                });
                                if (p.Quantity > qua)
                                    hasDone = false;
                            });
                            dealOrder.OrderStatus = (int)(hasDone ? OrderStatus.Stocked : OrderStatus.Stocking);
                        }
                    }
                    #endregion

                    db.DataContext.SaveChanges();
                    order.ID = dOrder.ID;
                    return order;
                }
            }
            return null;
        }
        /// <summary>
        /// 查询单据列表
        /// </summary>
        /// <param name="sea"></param>
        /// <returns></returns>
        public static ProductOrderCollection GetOrders(ProductOrderQuery sea)
        {
            var result = new ProductOrderCollection();
            using (DBCentre db = new DBCentre())
            {
                IQueryable<ProductOrder> q = db.DataContext.ProductOrders;
                if (sea != null)
                {
                    if (!string.IsNullOrEmpty(sea.OrderNo))
                        q = q.Where(p => p.OrderNo == sea.OrderNo);
                    if (sea.OperatorUserID > 0)
                        q = q.Where(p => p.OperatorUserID == sea.OperatorUserID);
                    if (sea.HouseID > 0)
                        q = q.Where(p => p.HouseID == sea.HouseID);
                    if (sea.OrderDateBefore != null)
                        q = q.Where(p => p.NoteDate.CompareTo(sea.OrderDateBefore.Value) >= 0);
                    if (sea.OrderDateAfter != null)
                        q = q.Where(p => p.NoteDate.CompareTo(sea.OrderDateAfter.Value) <= 0);
                    if (sea.Method > 0)
                        q = q.Where(p => p.Method == sea.Method);
                }
                var n = q.Count();
                if (n > 0)
                {
                    q = q.OrderByDescending(p => p.ID);
                    if (sea != null && sea.PageSize > 0)
                        q = q.Skip(sea.PageSize * sea.PageIndex).Take(sea.PageSize);
                    var lst = q.ToList();
                    result = Convertor.ConvertCollection<ProductOrderModel, ProductOrder, ProductOrderCollection>(lst);
                    result.TotalRecordsCount = n;
                    foreach (var m in result)
                    {
                        var d = lst.Find(p => p.OrderNo == m.OrderNo);
                        if (sea.GetHouse)
                            m.Warehouse = Convertor.ConvertTo<WarehouseModel, Warehouse>(d.Warehouse);
                        if (sea.GetItems)
                            m.Items = Convertor.ConvertCollection<ProductOrderDetailModel, ProductOrderDetail, ProductOrderDetailCollection>(d.ProductOrderDetails);
                        if (sea.GetDealOrder && d.DealOrder!=null)
                            m.AssociatedDealOrder = Convertor.ConvertTo<DealOrderModel, DealOrder>(d.DealOrder);
                        if (sea.GetOperator)
                            m.Operator = d.User.RealName;
                    }
                }
            }
            return result;
        }

        public static ProductOrderModel GetOrder(string orderNo)
        {
            if (!string.IsNullOrEmpty(orderNo))
            {
                using (DBCentre db = new DBCentre())
                {
                    var d = db.DataContext.ProductOrders.FirstOrDefault(p => p.OrderNo == orderNo);
                    if (d != null)
                    {
                        var m = Convertor.ConvertTo<ProductOrderModel, ProductOrder>(d);
                        m.Items = Convertor.ConvertCollection<ProductOrderDetailModel, ProductOrderDetail, ProductOrderDetailCollection>(d.ProductOrderDetails);
                        m.Warehouse = Convertor.ConvertTo<WarehouseModel, Warehouse>(d.Warehouse);
                        foreach (var o in m.Items)
                        {
                            var di = d.ProductOrderDetails.FirstOrDefault(p => p.ID == o.ID);
                            o.Product = Convertor.ConvertTo<ProductModel, Product>(di.Product);
                            o.MaterialName = di.ProductMaterial.MaterialName;
                            o.ProcessName = di.ProductProcess.ProcessName;
                        }
                        return m;
                    }
                }
            }
            return null;
        }
        /// <summary>
        /// 盘存
        /// </summary>
        /// <param name="order"></param>
        /// <returns></returns>
        public static ProductOrderModel SetBalance(ProductOrderModel order)
        {
            if (order != null)
            {
                using (DBCentre db = new DBCentre())
                {
                    var orderMethod = (OrderMethod)Enum.Parse(typeof(OrderMethod), order.Method.ToString());
                    order.OrderNo = Comm.Orders.CreateOrderNo(db, orderMethod);
                    var dOrder = Convertor.ConvertFrom<ProductOrder, ProductOrderModel>(order);
                    foreach (var it in order.Items)
                    {
                        var quantity = it.Quantity;
                        decimal lastStock = 0; //上期库存
                        var stock = db.DataContext.ProductStocks.FirstOrDefault(p =>p.HouseID==order.HouseID && p.ProductID == it.ProductID && p.MaterialID == it.MaterialID && p.ProcessID == it.ProcessID && p.Size==it.Size);
                        if (stock != null)
                        {
                            lastStock = stock.Quantity;
                            stock.Quantity = it.Balance = lastStock + it.Quantity;
                            stock.LastUpdateOn = DateTime.Now;
                        }
                        else
                        {
                            it.Balance = it.Quantity;
                            stock = new ProductStock()
                            {
                                ProductID = it.ProductID,
                                MaterialID = it.MaterialID,
                                ProcessID = it.ProcessID,
                                Quantity = it.Quantity,
                                LastUpdateOn = DateTime.Now,
                                Size=it.Size,
                                HouseID=order.HouseID
                            };
                            db.DataContext.ProductStocks.Add(stock);
                        }
                        if (lastStock + quantity < 0)
                            throw new InvoicingException(string.Format("{0} 库存不足，目前库存量为：{1}", new object[] { it.Product.Module, lastStock }));
                        var dit = Convertor.ConvertFrom<ProductOrderDetail, ProductOrderDetailModel>(it);
                        dOrder.ProductOrderDetails.Add(dit);
                    }
                    db.DataContext.ProductOrders.Add(dOrder);
                    
                    db.DataContext.SaveChanges();
                    order.ID = dOrder.ID;
                    return order;
                }
            }
            return null;
        }
    }
}
